home *** CD-ROM | disk | FTP | other *** search
/ PCMania 30 / PCMania CD30.iso / pcmania / graf30 / tacs / readimg.c < prev    next >
C/C++ Source or Header  |  1988-04-27  |  20KB  |  876 lines

  1. #include <tiff.h>
  2.  
  3. #define LINE_SIZE 320
  4. #define BUFFER_SIZE 512
  5. #define NULL 0
  6. #define BITS_PER_BYTE    8
  7. #define ONE_D_MODIFIED_HUFFMAN    2
  8.  
  9. extern void bigfree();
  10. extern void debug();
  11. extern int sprintf();
  12.  
  13. extern SHORT read_header();
  14. extern SHORT read_tag();
  15. extern SHORT read_dirent();
  16. extern SHORT decompress_block();
  17. extern SHORT decompress_error;
  18.  
  19. extern BOOL access_ifd();
  20.  
  21. extern LONGPTR bigalloc();
  22. extern LONGPTR decblk;        /* decompression block */
  23. extern LONGPTR decblk2;
  24. extern SHORT l_compression;
  25.  
  26. extern LONG lseek();
  27. extern LONG bigRead();
  28.  
  29. /*
  30.  * Declaring a global variable to be "static" causes it to be considered
  31.  * global only within this source file.  Hence, these "statics" will be
  32.  * invisible to any other routines.  This avoids unnecessary name clashes
  33.  * and keeps these routines and variables out of the load map.
  34.  */
  35.  
  36. /* static routines */
  37. static LONG get_buffer();
  38.  
  39. static BOOL readimg_init();
  40. static BOOL read_strip_tables();
  41. static BOOL read_dirct_valu();
  42.  
  43. /* static global variables */
  44. static SHORT current_handle = (SHORT)(-1);
  45. SHORT readimg_handle = (SHORT)(-1);
  46. static SHORT image_width;
  47. static SHORT compression_type = 0;
  48. static SHORT residual = 0;
  49.  
  50. static BOOL decompress = FALSE;
  51. static BOOL initialize_read = FALSE;
  52. static BOOL one_at_a_time = FALSE;
  53.  
  54. static char *dc_ptr = NULL;
  55. static char temp_line_buff[LINE_SIZE];
  56. static char decomp_buffer[BUFFER_SIZE];
  57.  
  58. static LONG rows_per_strip;
  59. static LONG bytes_per_line;
  60. static LONG start_strip;
  61. static LONG num_strips;
  62. static LONG prev_start_strip = -1L;
  63. static LONG prev_num_strips = -1L;
  64. static LONG strip_index;
  65. static LONG current_line;
  66. static LONG current_byte;
  67. static LONG decomp_bytes_left = 0L;
  68. static LONG num_sb_count;
  69. static LONG off_sb_count;
  70. static LONG num_str_off;
  71. static LONG off_str_off;
  72. static LONG max_strip_size;
  73. static LONG file_position = -1L;
  74. static LONG next_line_to_read = -1L;
  75. static LONG save_file_position = -1L;
  76. static LONG number_of_bytes;
  77. static SHORT samp_per_pix;
  78. static SHORT bits_per_samp;
  79.  
  80. /*
  81.  * These globals are accessible by any routine.
  82.  */
  83. extern LONG far *so_table;
  84. extern LONG far *sbc_table;
  85.  
  86. LONG _TIFF_image_bytes_read;
  87. LONG _TIFF_image_lines_read;
  88. #ifdef DEBUG
  89. BOOL _TIFF_debug_flag = TRUE;
  90. #else
  91. BOOL _TIFF_debug_flag = FALSE;
  92. #endif /* DEBUG */
  93. LONG bytes_processed = 0;
  94.  
  95. #ifdef NOWINDOWS
  96. /*
  97.  * The flag for one-byte-at-a-time versus buffered mode is a static, so
  98.  * that no routine that is linked in can access it.  It is set or cleared
  99.  * by means of this SetBufferedMode() routine.    When debugging, compile
  100.  * with the NOWINDOWS flag defined if you want to be able to use this
  101.  * routine to alter this mode.    Without NOWINDOWS, this routine never
  102.  * gets compiled, and so there'd be no way to alter the buffering mode
  103.  * from the default value (default == buffered) short of using a debugger
  104.  * or patching the code.
  105.  */
  106. void
  107. SetBufferedMode(buffered)
  108. BOOL buffered;
  109. {
  110.     if(buffered)
  111.     {
  112.         one_at_a_time = FALSE;
  113.     }
  114.     else
  115.     {
  116.         one_at_a_time = TRUE;
  117.     }
  118. }
  119. #endif /* NOWINDOWS */
  120.  
  121. /* return position of top of IFD list (or zero if error) */
  122. LONG
  123. far get_1st_ifd(fhandle)
  124. SHORT fhandle;
  125. {
  126.  
  127.     static TIFF_HEADER curr_header;
  128.  
  129.     if(fhandle != current_handle)
  130.     {
  131.         current_handle = fhandle;
  132.         if(read_header(fhandle, (TIFF_HEADER far *)&curr_header) !=
  133.           TIFF_HEADER_SIZE)
  134.         {
  135.             return(0L);
  136.         }
  137.     }
  138.     return(curr_header.dir_offset);
  139. }
  140.  
  141. /* clean up image reading environment */
  142. SHORT
  143. close_read(fhandle)
  144. SHORT fhandle;
  145. {
  146.     /* reinitialize handles */
  147.     if(current_handle == fhandle)
  148.     {
  149.         current_handle = (SHORT)(-1);
  150.     }
  151.     if(readimg_handle == fhandle)
  152.     {
  153.         readimg_handle = (SHORT)(-1);
  154.     }
  155.  
  156.     /* free buffers, reinitialize pointers and sizes */
  157.     bigfree(sbc_table);
  158.     bigfree(so_table);
  159.     if(l_compression == ONE_D_MODIFIED_HUFFMAN) {
  160.         bigfree(decblk);
  161.         bigfree(decblk2);
  162.     }
  163.     sbc_table = 0L;
  164.     so_table = 0L;
  165.     file_position = -1L;
  166.     return(1);
  167. }
  168.  
  169. /* routine to read an image */
  170. LONG
  171. oread_image(fhandle, fdtype, plane, startpos, numlines, buffer, max_length)
  172. SHORT fhandle;
  173. SHORT fdtype;
  174. SHORT plane;
  175. LONG startpos;
  176. LONG numlines;
  177. LONGPTR buffer;
  178. LONG max_length;
  179. {
  180.     LONG ifd_offset = get_1st_ifd(fhandle);
  181.     LONG bytes_to_be_read;
  182.     LONG end_strip;
  183.     LONG start_offset;
  184.     LONG end_offset;
  185.     LONG current_pos;
  186.     LONG denominator;
  187.     LONG line_offset;
  188.     LONG line;
  189.     LONG n;
  190.     LONG decomp_seek;
  191.  
  192.     _TIFF_image_bytes_read = 0L;
  193.     _TIFF_image_lines_read = 0L;
  194.  
  195.     if(!ifd_offset)
  196.     {
  197.         file_position = -1L;
  198.         readimg_handle = -1;
  199.         return(0L);
  200.     }
  201.  
  202.     /*
  203.      * First, get the necessary information from the appropriate tags,
  204.      * but only do it if the file handle has changed.
  205.      */
  206.     if(readimg_handle != fhandle)
  207.     {
  208.         if(readimg_init(fhandle, fdtype))
  209.         {
  210.             file_position = -1L;
  211.             readimg_handle = -1;
  212.             return(0L);
  213.         }
  214.     }
  215.  
  216.     /* decide where to start and how many strips to read */
  217.     if(rows_per_strip)
  218.     {
  219.         start_strip = startpos / rows_per_strip;
  220.         end_strip = ((numlines - 1) + startpos) /
  221.           rows_per_strip;
  222.     }
  223.     else
  224.     {
  225.         start_strip = 0L;
  226.         end_strip = 0L;
  227.     }
  228.  
  229.     /* make sure final strip is contained in file */
  230.     if(end_strip >= num_str_off)
  231.     {
  232.         end_strip = num_str_off - 1;
  233.     }
  234.     if(end_strip >= num_sb_count)
  235.     {
  236.         end_strip = num_sb_count - 1;
  237.     }
  238.  
  239.     /* don't read if adjusted end strip is below start strip */
  240.     if(end_strip < start_strip)
  241.     {
  242.         readimg_handle = -1;
  243.         file_position = -1L;
  244.         return(0L);
  245.     }
  246.     num_strips = (end_strip - start_strip) + 1;
  247.  
  248.     /* re-read the strip tables if necessary */
  249.     if(start_strip != prev_start_strip ||
  250.       num_strips != prev_num_strips ||
  251.       prev_start_strip == -1L ||
  252.       prev_num_strips == -1L ||
  253.       !sbc_table ||
  254.       !so_table)
  255.     {
  256.  
  257.       /* new addition to handle rows per strip = image length */
  258.       /* vj 1/12/87                       */
  259.  
  260.          if(num_str_off == 1)
  261.          {
  262.         if(read_dirct_valu(fhandle))
  263.         {
  264.            file_position = -1L;
  265.            readimg_handle = -1;
  266.            return(0L);
  267.         }
  268.  
  269.          }
  270.  
  271.       /* --                            -- */
  272.          else
  273.          {
  274.         if(read_strip_tables(fhandle))
  275.         {
  276.             file_position = -1L;
  277.             readimg_handle = -1;
  278.             return(0L);
  279.         }
  280.          }
  281.     }
  282.  
  283.     /* get number of bytes per line and total bytes needed */
  284.     bytes_per_line = ((LONG)samp_per_pix * (LONG)bits_per_samp * (LONG)image_width) + BITS_PER_BYTE-1;
  285.  
  286.     /* wrong, wrong wrong...... bytes_per_line /= denominator; 
  287.        bytes per line will only be bytes per line only if you divide
  288.        the image_width by 8.  Not 8 * number of bits per pixel */
  289.  
  290.     bytes_per_line /= BITS_PER_BYTE;   /* bits per byte better be 8 */
  291.  
  292.     bytes_to_be_read = bytes_per_line * numlines;
  293. #ifdef DEBUG
  294. printf("bytes= %d\n",bytes_per_line);
  295. printf("read = %d\n",bytes_to_be_read);
  296. #endif
  297.  
  298.     /* make sure we haven't exceeded maximum buffer size */
  299.     if(bytes_to_be_read > max_length)
  300.     {
  301.         readimg_handle = -1;
  302.         bigfree(sbc_table);
  303.         bigfree(so_table);
  304.         so_table = 0L;
  305.         sbc_table = 0L;
  306.         file_position = -1L;
  307.         return(0L);
  308.     }
  309.  
  310.     /* point to beginning of first line */
  311.     if(rows_per_strip)
  312.     {
  313.         line_offset = startpos - start_strip * rows_per_strip;
  314.     }
  315.     else
  316.     {
  317.         line_offset = startpos;
  318.     }
  319.     strip_index = start_strip;
  320.     if(next_line_to_read != -1L && next_line_to_read == startpos)
  321.     {
  322.         decomp_seek = save_file_position;
  323.     }
  324.     else
  325.     {
  326.         decomp_seek = -1L;
  327.     }
  328.     save_file_position = -1L;
  329.     next_line_to_read = -1L;
  330.  
  331.     /* read the image data now */
  332.     if(decompress)
  333.     {
  334.         residual = 0;
  335.         initialize_read = TRUE;
  336.         current_byte = 0L;
  337.  
  338.         /*
  339.          * If our start line doesn't begin at the top of the strip
  340.          * we have to decompress through the strip line by line,
  341.          * ignoring each line until we're positioned at this start
  342.          * line.
  343.          */
  344.         if(line_offset > 0)
  345.         {
  346. debug("    positioning ...\n");
  347.             if(decomp_seek < 0L)
  348.             {
  349.                 /* read and ignore the lines */
  350.                 n = line_offset;
  351.                 while(n-- > 0)
  352.                 {
  353.                     decompress_block(
  354.                       (LONGPTR)temp_line_buff,
  355.                       image_width, 1);
  356.                     if(bytes_processed !=
  357.                       bytes_per_line)
  358.                     {
  359.                         break;
  360.                     }
  361.                 }
  362.  
  363.                 /* if there was some error, get out */
  364.                 if(n > 0)
  365.                 {
  366.                     readimg_handle = -1;
  367.                     bigfree(sbc_table);
  368.                     bigfree(so_table);
  369.                     so_table = 0L;
  370.                     sbc_table = 0L;
  371.                     file_position = -1L;
  372.                     return(0L);
  373.                 }
  374.                 file_position = lseek(readimg_handle, 0L, 1);
  375.             }
  376.             else
  377.             {
  378.                 file_position = lseek(readimg_handle,
  379.                   decomp_seek, 0);
  380.                 if(file_position != decomp_seek)
  381.                 {
  382.                     readimg_handle = -1;
  383.                     bigfree(sbc_table);
  384.                     bigfree(so_table);
  385.                     so_table = 0L;
  386.                     sbc_table = 0L;
  387.                     file_position = -1L;
  388.                     return(0L);
  389.                 }
  390.                 initialize_read = FALSE;
  391.                 decomp_bytes_left = 0L;
  392.                 current_byte = file_position - so_table[0];
  393.             }
  394. debug("    after positioning, offset %ld\n", file_position);
  395.         }
  396.  
  397.         /*
  398.          * If we're here, we are now positioned at the
  399.          * correct start position in the image file.
  400.          * Just read lines until we're done or until
  401.          * there's an error.
  402.          */
  403.         n = numlines;
  404.         while(n-- > 0 && bytes_to_be_read > 0)
  405.         {
  406.  
  407.             /*
  408.              * We can only read an integral number of lines
  409.              * when decompressing.    Hence, we exit if the
  410.              * next line read will push us past the total
  411.              * number of bytes requested.
  412.              */
  413.             if(bytes_to_be_read < bytes_per_line)
  414.             {
  415.                 break;
  416.             }
  417.  
  418.             /* decompress into the caller's buffer */
  419.             number_of_bytes = 0L;
  420.             decompress_block(buffer, image_width, 1);
  421. debug("    read: %ld bytes decompressed into %ld bytes, offset %ld\n",
  422.  number_of_bytes, bytes_processed, file_position);
  423.             buffer += bytes_processed;
  424.             _TIFF_image_bytes_read += bytes_processed;
  425.             bytes_to_be_read -= bytes_processed;
  426.             if(bytes_processed != bytes_per_line)
  427.             {
  428.                 break;
  429.             }
  430.         }
  431.     }
  432.     else    /* read uncompressed data */
  433.     {
  434.         current_byte = line_offset * bytes_per_line;
  435.  
  436.         /* read data directly into caller's data buffer */
  437.         while(bytes_to_be_read > 0)
  438.         {
  439.             /*
  440.              * Try to get all remaining data into caller's
  441.              * data buffer.
  442.              */
  443.             LONG len = get_buffer(buffer, bytes_to_be_read);
  444.  
  445.             /* if no data was retrieved, we're finished */
  446.             if(len <= 0)
  447.             {
  448.                 break;
  449.             }
  450.  
  451.             /*
  452.              * Adjust pointers/totals by actual number of
  453.              * bytes read.
  454.              */
  455.             buffer += len;
  456.             _TIFF_image_bytes_read += len;
  457.             bytes_to_be_read -= len;
  458.         }
  459.     }
  460.  
  461.     _TIFF_image_lines_read = _TIFF_image_bytes_read;
  462.     _TIFF_image_lines_read /= bytes_per_line;
  463.     save_file_position = file_position;
  464.     next_line_to_read = startpos + _TIFF_image_lines_read;
  465.     return(_TIFF_image_lines_read);
  466. }
  467.  
  468. /* read appropriate tags and such */
  469. static BOOL
  470. readimg_init(fhandle, fdtype)
  471. SHORT fhandle;
  472. SHORT fdtype;
  473. {
  474.     TIFF_DIR_ENTRY dirent;
  475.  
  476.     readimg_handle = fhandle;
  477.     bigfree(so_table);
  478.     bigfree(sbc_table);
  479.     start_strip = -1L;
  480.     prev_start_strip = -1L;
  481.     num_strips = 0L;
  482.     prev_num_strips = -1L;
  483.     so_table = 0L;
  484.     sbc_table = 0L;
  485.     decomp_bytes_left = 0L;
  486.     dc_ptr = NULL;
  487.     num_sb_count = 0L;
  488.     off_sb_count = 0L;
  489.     num_str_off = 0L;
  490.     off_str_off = 0L;
  491.     max_strip_size = 0L;
  492.     compression_type = 0;
  493.     decompress = FALSE;
  494.     next_line_to_read = -1L;
  495.     save_file_position = -1L;
  496.  
  497.     if(!read_tag(fhandle, fdtype, IMAGE_WIDTH_TAG,
  498.       (LONGPTR)&image_width, (SHORT)SHORT_SIZE))
  499.     {
  500.         return(TRUE);
  501.     }
  502.  
  503.     /* bits per sample */
  504.     if(!read_tag(fhandle, fdtype, BITS_PER_SAMPLE_TAG,
  505.       (LONGPTR)&bits_per_samp, (SHORT)SHORT_SIZE))
  506.  
  507.     {
  508.         bits_per_samp = 1;
  509.     }
  510.  
  511.     /* samples_per_pixel */
  512.     if(!read_tag(fhandle, fdtype, SAMPLES_PER_PIXEL_TAG,
  513.       (LONGPTR)&samp_per_pix, (SHORT)SHORT_SIZE))
  514.     {
  515.         samp_per_pix = 1;
  516.     }
  517.  
  518.     /* rows per strip */
  519.     if(!read_tag(fhandle, fdtype, ROWS_PER_STRIP_TAG,
  520.       (LONGPTR)&rows_per_strip, (SHORT)LONG_SIZE))
  521.     {
  522.         rows_per_strip = 0L;
  523.     }
  524.  
  525.     /* compression */
  526.     if(!read_tag(fhandle, fdtype, COMPRESSION_TAG,
  527.       (LONGPTR)&compression_type, (SHORT)SHORT_SIZE))
  528.     {
  529.         decompress = FALSE;
  530.     }
  531.     else
  532.     {
  533.         /*
  534.          * Currently (9/7/86), the only compression this
  535.          * routine can handle is the 1-Dimensional Modified
  536.          * Huffman run length encoding technique.
  537.          */
  538.         switch(compression_type)
  539.         {
  540.         case ONE_D_MOD_HUFFMAN:
  541.             decompress = TRUE;
  542.             break;
  543.  
  544.         default:
  545.             decompress = FALSE;
  546.             compression_type = 0;
  547.         }
  548.     }
  549.  
  550.     /* strip offsets */
  551.     if(!read_dirent(fhandle, fdtype, STRIP_OFFSETS_TAG,
  552.       (TIFF_DIR_ENTRY far *)&dirent))
  553.     {
  554.         return(TRUE);
  555.     }
  556.     num_str_off = dirent.length;
  557.     off_str_off = dirent.value_offset;
  558.  
  559.     /* strip byte counts */
  560.     if(!read_dirent(fhandle, fdtype, STRIP_BYTE_COUNTS_TAG,
  561.       (TIFF_DIR_ENTRY far *)&dirent))
  562.     {
  563.         return(TRUE);
  564.     }
  565.     num_sb_count = dirent.length;
  566.     off_sb_count = dirent.value_offset;
  567.  
  568. debug("    # of strip offsets = %lu, 1st strip offset at %lu\n",
  569.  num_str_off, off_str_off);
  570. debug("    # of strip byte counts = %lu, 1st strip byte count at %lu\n",
  571.  num_sb_count, off_sb_count);
  572.     return(FALSE);
  573. }
  574.  
  575. /* read the strip offsets and strip bytes counts tables */
  576. static BOOL
  577. read_strip_tables(fhandle)
  578. SHORT fhandle;
  579. {
  580.     LONG n;
  581.     LONG seek_pos;
  582.     LONG read_len;
  583.  
  584.     prev_start_strip = start_strip;
  585.     prev_num_strips = num_strips;
  586.  
  587.     bigfree(so_table);
  588.     bigfree(sbc_table);
  589.     so_table = 0L;
  590.     sbc_table = 0L;
  591.  
  592.     /* allocate space for strip offsets table */
  593.     so_table = (LONG far *)bigalloc(num_strips * (LONG)LONG_SIZE);
  594.     if(!so_table)
  595.     {
  596.         readimg_handle = -1;
  597.         return(TRUE);
  598.     }
  599.  
  600.     /* allocate space for strip byte counts table */
  601.     sbc_table = (LONG far *)bigalloc(num_strips *
  602.       (LONG)LONG_SIZE);
  603.     if(!sbc_table)
  604.     {
  605.         readimg_handle = -1;
  606.         bigfree(so_table);
  607.         so_table = 0L;
  608.         return(TRUE);
  609.     }
  610.  
  611.     /* read appropriate portion of strip offsets table */
  612.     seek_pos = off_str_off + start_strip * (LONG)LONG_SIZE;
  613.     if(lseek(fhandle, seek_pos, 0) != seek_pos)
  614.     {
  615.         readimg_handle = -1;
  616.         file_position = -1L;
  617.         bigfree(sbc_table);
  618.         bigfree(so_table);
  619.         so_table = 0L;
  620.         sbc_table = 0L;
  621.         return(TRUE);
  622.     }
  623.     read_len = num_strips * (LONG)LONG_SIZE;
  624.     if(bigRead(fhandle, so_table, read_len) != read_len)
  625.     {
  626.         readimg_handle = -1;
  627.         file_position = -1L;
  628.         bigfree(sbc_table);
  629.         bigfree(so_table);
  630.         so_table = 0L;
  631.         sbc_table = 0L;
  632.         return(TRUE);
  633.     }
  634.  
  635.     /* read appropriate portion of strip byte counts table */
  636.     seek_pos = off_sb_count + start_strip * (LONG)LONG_SIZE;
  637.     if(lseek(fhandle, seek_pos, 0) != seek_pos)
  638.     {
  639.         readimg_handle = -1;
  640.         file_position = -1L;
  641.         bigfree(sbc_table);
  642.         bigfree(so_table);
  643.         so_table = 0L;
  644.         sbc_table = 0L;
  645.         return(TRUE);
  646.     }
  647.     read_len = num_strips * (LONG)LONG_SIZE;
  648.     if(bigRead(fhandle, sbc_table, read_len) != read_len)
  649.     {
  650.         readimg_handle = -1;
  651.         file_position = -1L;
  652.         bigfree(sbc_table);
  653.         bigfree(so_table);
  654.         so_table = 0L;
  655.         sbc_table = 0L;
  656.         return(TRUE);
  657.     }
  658.  
  659.     /* go through table of strip byte counts and get maximum */
  660.     max_strip_size = 0L;
  661.     for(n = 0; n < num_strips; ++n)
  662.     {
  663. debug("    strip %4ld: offset %lu, byte count %lu\n", n, so_table[n],
  664.  sbc_table[n]);
  665.         if(max_strip_size < sbc_table[n])
  666.         {
  667.             max_strip_size = sbc_table[n];
  668.         }
  669.     }
  670.  
  671.     return(FALSE);
  672. }
  673.  
  674. /* get a buffer from the file */
  675. static LONG
  676. get_buffer(data_buffer, size)
  677. LONGPTR data_buffer;
  678. LONG size;
  679. {
  680.     LONG table_offset = strip_index - start_strip;
  681.     LONG bytes_per_strip = sbc_table[table_offset];
  682.     LONG seek_pos;
  683.     LONG read_len;
  684.     LONG len;
  685.  
  686.     /* see if we need to go to the next strip */
  687.     if(current_byte >= bytes_per_strip)
  688.     {
  689.         /* we're done if strip table is exhausted */
  690.         if(++table_offset >= num_strips)
  691.         {
  692.             return(-1L);
  693.         }
  694.         bytes_per_strip = sbc_table[table_offset];
  695.  
  696.         /* we're done if it's an empty strip */
  697.         if(bytes_per_strip < 1)
  698.         {
  699.             return(-1L);
  700.         }
  701.         strip_index = start_strip + table_offset;
  702.         current_byte = 0L;
  703.         residual = 0;
  704.     }
  705.  
  706.     /*
  707.      * Seek to the appropriate position.  Do this each time in case
  708.      * the caller has seeked elsewhere in the interim.
  709.      */
  710.     seek_pos = so_table[table_offset] + current_byte;
  711.     if((file_position = lseek(readimg_handle, seek_pos, 0)) != seek_pos)
  712.     {
  713.         file_position = -1L;
  714.         return(-1L);
  715.     }
  716.  
  717.     /* figure out how much to read and then do it */
  718.     read_len = size;
  719.     if(read_len + current_byte > bytes_per_strip)
  720.     {
  721.         read_len = bytes_per_strip - current_byte;
  722.     }
  723.     if(read_len <= 0)
  724.     {
  725.         return(-1L);
  726.     }
  727.     len = bigRead(readimg_handle, data_buffer, read_len);
  728.     if(len >= 0)
  729.     {
  730.         current_byte += len;
  731.     }
  732.     return(len);
  733. }
  734.  
  735. /*
  736.  * This module is to read the stripoffset and stripbytecount values
  737.  * when rows per strip is equal to the image length, 1/12/87
  738.  */
  739.  
  740. static    BOOL
  741. read_dirct_valu(fhandle)
  742. SHORT fhandle;
  743. {
  744.  
  745.     LONG    n;
  746.     prev_start_strip = start_strip;
  747.     prev_num_strips = num_strips;
  748.  
  749.     bigfree(so_table);
  750.     bigfree(sbc_table);
  751.     so_table = 0L;
  752.     sbc_table = 0L;
  753.  
  754.     /* allocate space for strip offsets table */
  755.     so_table = (LONG far *)bigalloc(num_strips * (LONG)LONG_SIZE);
  756.     if(!so_table)
  757.     {
  758.         readimg_handle = -1;
  759.         return(TRUE);
  760.     }
  761.  
  762.     /* allocate space for strip byte counts table */
  763.     sbc_table = (LONG far *)bigalloc(num_strips *
  764.       (LONG)LONG_SIZE);
  765.     if(!sbc_table)
  766.     {
  767.         readimg_handle = -1;
  768.         bigfree(so_table);
  769.         so_table = 0L;
  770.         return(TRUE);
  771.     }
  772.  
  773.     *so_table = off_str_off;
  774.     *sbc_table = off_sb_count;
  775.  
  776.     max_strip_size = 0L;
  777.     for(n = 0; n < num_strips; ++n)
  778.     {
  779. debug("    strip %4ld: offset %lu, byte count %lu\n", n, so_table[n],
  780.  sbc_table[n]);
  781.         if(max_strip_size < sbc_table[n])
  782.         {
  783.             max_strip_size = sbc_table[n];
  784.         }
  785.     }
  786.  
  787.     return(FALSE);
  788.  
  789. }
  790.  
  791. /*
  792.  * General get-byte routine.  It's needed for decompression, so I
  793.  * might as well use it for uncompressed data as well.
  794.  */
  795. SHORT
  796. GetDecompByte()
  797. {
  798.     SHORT ch;
  799.     LONG table_offset = strip_index - start_strip;
  800.     LONG bytes_per_strip = sbc_table[table_offset];
  801.     LONG seek_pos;
  802.  
  803. #ifdef NOWINDOWS
  804.     if(one_at_a_time)
  805.     {
  806.         if(initialize_read)
  807.         {
  808.             current_byte = bytes_per_strip;
  809.             --table_offset;
  810.             initialize_read = FALSE;
  811.         }
  812.         /* see if we need to go to the next strip */
  813.         if(current_byte >= bytes_per_strip)
  814.         {
  815.             /* we're done if strip table is exhausted */
  816.             if(++table_offset >= num_strips)
  817.             {
  818.                 return((SHORT)0xffff);
  819.             }
  820.             bytes_per_strip = sbc_table[table_offset];
  821.  
  822.             /* we're done if it's an empty strip */
  823.             if(bytes_per_strip < 1L)
  824.             {
  825.                 return((SHORT)0xffff);
  826.             }
  827.             strip_index = start_strip + table_offset;
  828.             current_byte = 0L;
  829.             residual = 0;
  830.             seek_pos = so_table[table_offset];
  831.             if((file_position = lseek(readimg_handle, seek_pos,
  832.               0)) != seek_pos)
  833.             {
  834.                 file_position = -1L;
  835.                 return((SHORT)0xffff);
  836.             }
  837.         }
  838.  
  839.         if(bigRead(readimg_handle, (LONGPTR)&ch, 1L) < 1L)
  840.         {
  841.             return((SHORT)0xffff);
  842.         }
  843.         ++current_byte;
  844.         ++number_of_bytes;
  845.         file_position = lseek(readimg_handle, 0L, 1);
  846.         return(ch & 0xff);
  847.     }
  848.     else
  849.     {
  850. #endif /* NOWINDOWS */
  851.         /* read next buffer if necessary */
  852.         if(decomp_bytes_left <= 0 || !dc_ptr)
  853.         {
  854.             decomp_bytes_left =
  855.               get_buffer((LONGPTR)decomp_buffer,
  856.               (LONG)BUFFER_SIZE);
  857.  
  858.             /* if error or eof, return 0xffff */
  859.             if(decomp_bytes_left <= 0)
  860.             {
  861.                 return((SHORT)0xffff);
  862.             }
  863.             dc_ptr = decomp_buffer;
  864.         }
  865.  
  866.         /* return next character */
  867.         --decomp_bytes_left;
  868.         ++file_position;
  869.         ++number_of_bytes;
  870.         ch = (SHORT)(*dc_ptr++);
  871.         return(ch & 0xff);
  872. #ifdef NOWINDOWS
  873.     }
  874. #endif /* NOWINDOWS */
  875. }
  876.